#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define FILEMAXN 100
#define OPMAXN 100
#define NAMEMAXN 100
#define PATHMAXN 100
#define  StorageBlcoks 1024//将一块硬盘分成1024个物理块
#define StorageBlcoksBlockSize 1024//一个物理块的大小为1024b即1kb
#define BACKSPACE 127   //删除的asccll码值
enum STATUS {OCCUPIED = 0,FREE = 1};//内存块的状态
enum action {Read, Write,execute,delete};//需要执行哪些操作
//假设这里一个字母为1kb
typedef struct FCB{
	char name[NAMEMAXN];//文件夹名或文件名
	char path[PATHMAXN];//记录当前路径
	char end[NAMEMAXN];//文件后缀名
	int flag;//区分 文件夹 和 文件  文件夹----->0  |||||||||  文件）——>1
	char createTime[20];//创建日期
	int fileNumber;//记录当前节点的文件数量
	struct FCB ** files;//该文件夹包含的文件或文件夹列表
	struct FCB *parent;//上级目录
	int storgeBlcokId;
	int fileSize;// kb
	char permission[3];//读写执行 1 1 1
	struct user *user;//表示该目录属于哪个用户
}FCB,*FCB_Ptr;
typedef struct StorgeBlock{
	enum STATUS status;
	//char fileContent[StorageBlcoksBlockSize];//可以存储1024个字节
	char fileContent;
}StorgeBlock;
StorgeBlock storge[StorageBlcoksBlockSize];//拥有1024个内存块
int FAT[StorageBlcoksBlockSize];
FCB_Ptr root = NULL;
//日期函数，用于记录文件创建日期
char *getDateTime(){
  char static cur_time[20];
	time_t t;
	struct tm * lt;
	time(&t);
	lt = localtime(&t); //转为时间结构
	sprintf(cur_time, "%04d/%02d/%02d %02d:%02d:%02d",lt->tm_year+1900, lt->tm_mon+1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);
	//printf("%s",cur_time);
	return cur_time;
}
typedef struct user{
	char username[16];
	char password[16];
	struct user *next;
}user,*userPtr;

typedef struct opentable{//文件打开表
	FCB_Ptr FCB;
	struct opentable *next;
}opentable;
userPtr userList = NULL;
userPtr currentUser = NULL;


void deleteFile(FCB_Ptr file);
int permissonCheck(FCB_Ptr fileOrDir,enum action ac);

void storgeInit()
{
	for(int i=0;i<StorageBlcoksBlockSize;i++)
	{
		storge[i].status = FREE;
		FAT[i] = -2;
	}
//	 模拟磁盘被占用
	for(int i=0;i<StorageBlcoksBlockSize;i++)
	{
			int a = rand() % 1024; 
			//printf("%d\n",a);
			storge[a].status = OCCUPIED;
	}
}
void userListInit()
{
	userList = (userPtr)malloc(sizeof(user));
	strcpy(userList->username, "root");
	strcpy(userList->password, "root");
	userList->next = NULL;
}
//void initOpen()
//{
//	opentable * openTable = (opentable *)malloc(sizeof(opentable));
//	openTableHead = openTable;
//	//FCB *root = (FCB *) malloc(sizeof(FCB));
//	openTableHead->FCB = NULL;
//	openTableHead->next = NULL;
//}
void initOpen()
{
	
	opentable *openTableHead = (opentable*)malloc(sizeof(opentable));
	openTableHead->FCB = NULL;
	openTableHead->next = NULL;
}
void display_StorgeStatus()
{
	for(int i=0;i<StorageBlcoksBlockSize/20;i++)
	{
		int m = i*20;
		int n = m+19;
		printf("%4d--%-4d:",i*20,n);
		for(int j=m;j<n+1;j++)
		{
			printf("%d\t",storge[j].status);
		}
		printf("\n");
	}
	printf("%4d--%-4d:",1020,1023);
	for(int i=1020;i<1024;i++)
	printf("%d\t",storge[i].status);
	printf("\n");

}
//初始化,生成root节点
FCB_Ptr InitFileSystem()
{
	FCB *root = (FCB *) malloc(sizeof(FCB));
	root->files = NULL;
	root->parent = NULL;
	root->fileNumber = 0;
	root->flag = 0;
	root->user = userList;
	strcpy(root->name, "root"); //字符串拷贝函数
	strcpy(root->path, "/root");
	return root;
}
int nameIsExist(FCB_Ptr currentFCB_Ptr,char Name[],int flag,char end[])
{
	if(currentFCB_Ptr->files == NULL){
		return -1;
	}
	for(int i = 0; i < currentFCB_Ptr->fileNumber; i++){
			if(flag == 1){//文件还要再检查后缀
				if(strcmp(currentFCB_Ptr->files[i]->name, Name) == 0 && strcmp(currentFCB_Ptr->files[i]->end, end) == 0)
					return 1;//	存在
		}
			else
			{
				if(strcmp(currentFCB_Ptr->files[i]->name, Name) == 0)
					return 1;
			}
	}
	return 0;//不存在
}
//文件夹创建
void makeDirectory(FCB_Ptr currentFCB_Ptr,char name[])
{
//	printf("%s\n",name);
	
	if(nameIsExist(currentFCB_Ptr,name,0,NULL) == 1){
		printf("目录已存在\n");
		return;
	}
	if(currentFCB_Ptr->files == NULL){
		currentFCB_Ptr->files = (FCB **)malloc(FILEMAXN * sizeof(FCB_Ptr));//分配100个子文件（夹）指针
	}
//	FCB_Ptr newFCB = currentFCB_Ptr->files[currentFCB_Ptr->fileNumber];
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber] = (FCB_Ptr) malloc(sizeof(FCB));
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->files = NULL;//子文件（夹）为空
	strcpy(currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->createTime, getDateTime());
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->parent = currentFCB_Ptr;//新文件夹的上级目录为传入的当前目录
	strcpy(currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->name, name);//给文件夹起名
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->fileNumber = 0;
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->flag = 0;
	//富裕权限
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->permission[0] = 'r';
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->permission[1] = 'w';
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->permission[2] = 'x';
	//以下代码生成当前路径
	char tmp[PATHMAXN];
	strcpy(tmp, currentFCB_Ptr->path);
	strcat(tmp, "/");
	strcat(tmp, name);
	strcpy(currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->path, tmp);
	//printf("%s",currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->createTime);
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->user = currentUser;
	currentFCB_Ptr->fileNumber++;

//	return currentFCB_Ptr;
}
//文件创建
void makeFile(FCB_Ptr currentFCB_Ptr,char fileName[],char end[])
{
	if(nameIsExist(currentFCB_Ptr,fileName,1,end) == 1){
		printf("文件已存在\n");
		return;
	}
	if(currentFCB_Ptr->files == NULL){
		currentFCB_Ptr->files = (FCB **)malloc(FILEMAXN * sizeof(FCB_Ptr));//分配100个子文件（夹）指针
	}
//	FCB_Ptr newFCB = currentFCB_Ptr->files[currentFCB_Ptr->fileNumber];
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber] = (FCB_Ptr) malloc(sizeof(FCB));
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->files = NULL;//子文件（夹）为空
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->parent = currentFCB_Ptr;//新文件夹的上级目录为传入的当前目录
	strcpy(currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->name, fileName);//给文件起名
	strcpy(currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->end, end);
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->fileNumber = 0;
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->flag = 1;//创建文件，标记为1
	strcpy(currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->createTime, getDateTime());
	//赋予权限
	if(strcmp(end, "exe") == 0)
	{
		currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->permission[0] = '-';
		currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->permission[1] = '-';
		currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->permission[2] = 'x';
	}
	else{
		currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->permission[0] = 'r';
		currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->permission[1] = 'w';
		currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->permission[2] = 'x';
	}
	currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->user = currentUser;
	//size == 0 的情况
	int i = 0;
	while(1)
	{
		if(storge[i].status == FREE){
			storge[i].status = OCCUPIED;
			currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->storgeBlcokId = i;
			currentFCB_Ptr->files[currentFCB_Ptr->fileNumber]->fileSize = 1;
			FAT[i] = -1;
			break;
		}
		i++;
	}
	currentFCB_Ptr->fileNumber++;
	
}
void showCurrentDirectoryAllFile(FCB_Ptr currentFCB_Ptr)
{
	printf(".  ..  ");
	if(currentFCB_Ptr == root->files[2] && strcmp(currentUser->username, "root") != 0)//进入用户文件夹。需要做隐藏处理
	{			
		for(int i = 0; i < currentFCB_Ptr->fileNumber; i++){
		if(strcmp(currentFCB_Ptr->files[i]->name, currentUser->username) == 0)
		{
			printf("%s", currentFCB_Ptr->files[i]->name);
			if(currentFCB_Ptr->files[i]->flag == 1){//假如是文件的话，就加上文件后缀
				printf(".%s  ", currentFCB_Ptr->files[i]->end);
			}
			else{
				printf("  ");
			}
		}
		else 
			continue;
		}
		printf("\n");
	}
	else{
		for(int i = 0; i < currentFCB_Ptr->fileNumber; i++){
			printf("%s", currentFCB_Ptr->files[i]->name);
			if(currentFCB_Ptr->files[i]->flag == 1){//假如是文件的话，就加上文件后缀
				printf(".%s  ", currentFCB_Ptr->files[i]->end);
			}
			else{
				printf("  ");
			}
		}
		printf("\n");

	}
}
void showCurrentDirectoryAllFileDetail(FCB_Ptr currentFCB_Ptr)
{
	if(currentFCB_Ptr == root->files[2] && strcmp(currentUser->username, "root") != 0)//进入用户文件夹。需要做隐藏处理
	{
		//printf(".  ..  \n");
		printf("<DIR>\troot\t\trwx\t  2021/11/20 20:30:43\t  .\n");
		printf("<DIR>\troot\t\trwx\t  2021/11/20 20:30:43\t  ..\n");
		for(int i = 0; i < currentFCB_Ptr->fileNumber; i++){
			if(strcmp(currentFCB_Ptr->files[i]->name, currentUser->username) == 0)
			{
				if(currentFCB_Ptr->files[i]->flag == 0){
					printf("<DIR>\t");
				}
				else{
					printf("<--->\t");
				}
				printf("%-12s%s\t  %s\t  %s", currentFCB_Ptr->files[i]->user->username,currentFCB_Ptr->files[i]->permission,currentFCB_Ptr->files[i]->createTime,currentFCB_Ptr->files[i]->name);
				if(currentFCB_Ptr->files[i]->flag == 1){//假如是文件的话，就加上文件后缀
					printf(".%s\t\t", currentFCB_Ptr->files[i]->end);
					printf("%dkb\n",currentFCB_Ptr->files[i]->fileSize);
				}
				else{
					printf("\n");
				}
			}
			else
				continue;
		}
		printf("\n");
	}
	else{
		//printf(".  ..  \n");
		printf("<DIR>\troot\t\trwx\t  2021/11/20 20:30:43\t  .\n");
		printf("<DIR>\troot\t\trwx\t  2021/11/20 20:30:43\t  ..\n");
		for(int i = 0; i < currentFCB_Ptr->fileNumber; i++){
			if(currentFCB_Ptr->files[i]->flag == 0){
				printf("<DIR>\t");
			}
			else{
				printf("<--->\t");
			}
//			
			printf("%-12s",currentFCB_Ptr->files[i]->user->username);
//			printf("\n%s\n%s\n",currentUser->username,currentFCB_Ptr->files[i]->user->username);
			//权限的显示需要根据登录的用户来选择显示
			if(strcmp(currentUser->username, currentFCB_Ptr->files[i]->user->username) == 0 ||strcmp(currentUser->username, "root")==0 )
				{	//如果是管理员的话，就该是什么样就是什么样或者是文件的主人
					printf("%s\t",currentFCB_Ptr->files[i]->permission);
				}
			else if(strcmp(currentUser->username, currentFCB_Ptr->files[i]->user->username) != 0 && strcmp(currentFCB_Ptr->files[i]->end, "exe") != 0){
				printf("r--\t");
			}
			else
				printf("--x\t");
			printf("  %s\t  %s",currentFCB_Ptr->files[i]->createTime,currentFCB_Ptr->files[i]->name);
			if(currentFCB_Ptr->files[i]->flag == 1){//假如是文件的话，就加上文件后缀
				printf(".%s\t\t", currentFCB_Ptr->files[i]->end);
				printf("%dkb\n",currentFCB_Ptr->files[i]->fileSize);
			}
			else{
				printf("\n");
			}
		}
		printf("\n");
	}
}
FCB_Ptr EnterTheDirectory(FCB_Ptr currentFCB_Ptr,char DirectoryName[])
{
	for(int i = 0; i < currentFCB_Ptr->fileNumber; i++){
		if(currentFCB_Ptr->files[i]->flag == 0
			&& strcmp(currentFCB_Ptr->files[i]->name, DirectoryName) == 0){
			return currentFCB_Ptr->files[i];
		}
	}
	return NULL;
}
void deleteDirectory(FCB_Ptr currentFCB_Ptr)
{
	//先序遍历(递归算法)
	if(currentFCB_Ptr)
		{
			for(int i = 0; i < currentFCB_Ptr->fileNumber; i++){
				if(currentFCB_Ptr->files[i]->flag == 1){//这是删除文件;
					printf("正在删除文件：%s.%s...\n",currentFCB_Ptr->files[i]->name,currentFCB_Ptr->files[i]->end);
					deleteFile(currentFCB_Ptr->files[i]);
				}else{
					deleteDirectory(currentFCB_Ptr->files[i]);
				}
			}
			printf("正在删除文件夹：%s...\n",currentFCB_Ptr->name);
			free(currentFCB_Ptr);
		}	
}
int DeleteFCB(FCB_Ptr currentFCB_Ptr,char name[])
{

		//删除目录
			printf("该操作会将该目录下的所有文件删除！是否继续？(y/n)：");
			char confirm;
			confirm = getchar();
			getchar();
			for(int i = 0; i < currentFCB_Ptr->fileNumber; i++)
			{
				if(confirm == 'y')
					{
						if(currentFCB_Ptr->files[i]->flag == 0
							&& strcmp(currentFCB_Ptr->files[i]->name, name) == 0)
							{
								if(permissonCheck(currentFCB_Ptr->files[i],delete)){
									//文件夹要使用递归删除，防止内存泄漏
									deleteDirectory(currentFCB_Ptr->files[i]);
									currentFCB_Ptr->files[i] = NULL;
									currentFCB_Ptr->fileNumber -- ;
									printf("删除成功!\n");
									return 1;
								}
								else{
									return 0;
								}
							}
					}
				else{
					printf("操作已取消\n");
					return 0;
				}
			}
			
	printf("文件(目录)不存在\n");
	return 0;//文件不存在
}
void writeFileContent(FCB_Ptr currentFCB)
{
	if(permissonCheck(currentFCB,Write)){
		printf("请选择追加写入还是覆盖写入：1.追加写入；2.覆盖写入\n");
		int choose;
		scanf("%d",&choose);
		int flag = 2;char fileContent[200];
		char text[200] = "\0";
		char texttmp[200] = "\0";
		printf("请输入需要写入的内容:\n");
		//getchar();
		while (gets(texttmp)) {
			if (strcmp(texttmp, ":wq") == 0) {
				break;
			}
			texttmp[strlen(texttmp)] = '\n';
			strcat(text, texttmp);
		}
		//将文本内容写入硬盘和磁盘表
		int size = 4;int firstFlag = 1;
		int pre = currentFCB->storgeBlcokId;
		int i = 0;
		int len = strlen(text)-2;int j = 0;//写入指针
		currentFCB->fileSize = len - 2;
		while(len > 0)
			{
				if(firstFlag == 1 )//第一个文件块存到开始的地方
				{
					storge[currentFCB->storgeBlcokId].fileContent = text[j++];
					firstFlag = 0;
				}
				else{//后续要更新FAT表
					if(storge[i].status == FREE){
						storge[i].status = OCCUPIED;
						storge[i].fileContent = text[j++];
						FAT[pre] = i;
						len--;
						pre = i;
					}
				}
				i++;
			}
		FAT[i-1] = -1;
	}
	else {
		return;
	}
}
//删除文件，不需要递归。是否外存物理块，更新FAT表
void deleteFile(FCB_Ptr file)
{
	if(permissonCheck(file,delete)){
		FCB_Ptr parent = file->parent;
		//通过FAT表释放外存物理块和FAT表
		int len = file->fileSize + 3;
		int pre = file->storgeBlcokId;
		int temp;
		while(len-- > 0)
			{
				storge[pre].status = FREE;
				temp = FAT[pre];
				FAT[pre] = -2;
				pre = temp;
			}
		//删除该目录通过父节点
		for(int i = 0; i < parent->fileNumber; i++)
			{
				if(parent->files[i] == file)
					{
						parent->fileNumber--;
						parent->files[i] = NULL;
						break;
					}
			}
		free(file);
	}
	else {
		return;
	}
	//输出整个FAT查看是否修改成功
//	for(int i=0;i<1024;i++)
//	{
//		printf("%d",FAT[i]);
//	}
}
void readFileContent(FCB_Ptr currentFCB)
{
	if(permissonCheck(currentFCB,Read))
	{
		int pre = currentFCB->storgeBlcokId;
		int len = currentFCB->fileSize;
		int i = currentFCB->storgeBlcokId;
		while(i != -1)
			{
				printf("%c",storge[i].fileContent);
				i = FAT[pre];
				pre = i;
			}
		printf("\n");
	}
	else {
		return;
	}
}
FCB_Ptr findByName(char name[],FCB_Ptr currentFCB_Ptr,char end[])
{
	if(currentFCB_Ptr->files == NULL){
		return NULL;
	}
	for(int i = 0; i < currentFCB_Ptr->fileNumber; i++){
		if(strcmp(currentFCB_Ptr->files[i]->end, end) == 0 && strcmp(currentFCB_Ptr->files[i]->end, end) == 0)
			return currentFCB_Ptr->files[i];//	存在
	}
	return NULL;
}
void openFile(FCB_Ptr file,opentable *openTableHead)
{
	opentable *newOpenTableItem = (opentable*)malloc(sizeof(opentable));
	newOpenTableItem->FCB = file;
	newOpenTableItem->next = openTableHead->next;
	openTableHead->next = newOpenTableItem;
}
void dispalyOpenTable(opentable *openTableHead)
{
	opentable *temp = openTableHead->next;
	if(temp == NULL){
		printf("暂无文件打开!\n");
	}
	else{
		while(temp)
			{
				printf("%s.%s\n",temp->FCB->name,temp->FCB->end);
				temp = temp->next;
			}
	}
}
void closeFile(FCB_Ptr file,opentable *openTableHead)
{
	opentable *temp = openTableHead;
	while(temp)
		{
			if(temp->next->FCB == file)
				{
					opentable *p = temp->next;
					temp->next = p->next;
					free(p);
					printf("关闭成功！\n");
					break;
				}
			temp = temp->next;
		}
}
void command()
{
}
int permissonCheck(FCB_Ptr fileOrDir,enum action ac)
{
		if(ac == delete){//文件删除操作
			if(strcmp(currentUser->username, fileOrDir->user->username) == 0 || strcmp(currentUser->username, "root") == 0)
				{	//管理员或目录拥有者
					return 1;
				}
			else{
				printf("没有权限执行此写操作！\n");
				return 0;
			}
		}
		else if(ac == Read){//文件读操作
			if(strcmp(currentUser->username, fileOrDir->user->username) == 0 || strcmp(currentUser->username, "root") == 0)
				{	//管理员或目录拥有者
					if(strcmp(fileOrDir->end, "exe") == 0){
						printf("该文件为只执行文件！不能执行此操作\n");
						return 0;
					}
					return 1;
				}
			else{
				printf("没有权限执行此写操作！\n");
				return 0;
			}
		}
		else if(ac == Write){//文件写操作
			if(strcmp(currentUser->username, fileOrDir->user->username) == 0 || strcmp(currentUser->username, "root") == 0)
				{	//管理员或目录拥有者
					if(strcmp(fileOrDir->end, "exe") == 0){
						printf("该文件为只执行文件！不能执行此操作\n");
						return 0;
					}
					return 1;
				}
			else{
				printf("没有权限执行此写操作！\n");
				return 0;
			}
		}
		else if (ac == execute){//文件执行操作
			if(strcmp(fileOrDir->end, "exe") == 0)
				{	
					return 1;
				}
			else{
				//printf("该文件为只执行文件！不能执行此操作\n");
				return 0;
			}
		}
	
		return 0;
}
void displayFileFAT(FCB_Ptr file)
{	
	int len = file->fileSize+4;
	int pre = file->storgeBlcokId;
	while(len-- >0)
	{
		printf("%d->",pre);
		pre = FAT[pre];
	}
	printf("\n");
}
/*
不用getch()实现密码的输入，回显为*，最大可输入16位数
*/
//使密码以*号输出
char * password_code(char *pass)
{
	int i=0;
	system("stty -icanon");                   //设置一次性读完操作，即getchar()不用回车也能获取字符
	system("stty -echo");                     //关闭回显，即输入任何字符都不显示
	while(i < 16)
		{
			pass[i]=getchar();                    //获取键盘的值到数组中
			if(i == 0 && pass[i] == BACKSPACE)
				{
					i=0;                              //若开始没有值，输入删除，则，不算值
					pass[i]='\0';
					continue;
				}
			else if(pass[i] == BACKSPACE)
				{
					printf("\b \b");                    //若删除，则光标前移，输空格覆盖，再光标前移
					pass[i]='\0';
					i=i-1;                              //返回到前一个值继续输入
					continue;                           //结束当前循环
				}
			else if(pass[i] == '\n')               //若按回车则，输入结束
			{
				pass[i]='\0';
				break;
			}
			else
				{
					printf("*");
				}
			i++;
		}
	system("stty echo");                    //开启回显
	system("stty icanon");                   //关闭一次性读完操作，即getchar()必须回车也能获取字符
	return pass;                            //返回最后结果
}
void newUser(char username[],char password[])
{
	userPtr new = (userPtr)malloc(sizeof(user));
	strcpy(new->username, username);
	strcpy(new->password, password);
	new->next = userList->next;
	userList->next = new;
}
void displayUserList()
{
	userPtr temp = userList;
	printf("%s\n",userList->username);
	while (temp) {
		printf("%s\n",temp->username);
		temp = temp -> next;
	}
}
int checkUser(char username[],char password[])
{
	userPtr temp = userList;
	while (temp) {
		if(strcmp(username, temp->username) == 0 && strcmp(password, temp->password) == 0)
		{
			currentUser = temp;
			return 1;//认证成功、
		}
		temp = temp -> next;
	}
	return 0;//失败
}
void testDirectory (FCB_Ptr root) {
	currentUser = userList;
	makeDirectory(root, "Bin");
	makeDirectory(root, "System");
	makeDirectory(root, "User");
	//创建用户文件夹
	makeDirectory(root->files[2], "luowenyang");
	newUser("luowenyang", "123456");
	makeDirectory(root->files[2], "TestUser");
	newUser("TestUser", "123456");
}
void help()
{
	printf("\n*************************************\n");
	printf("命令文档：\n");
	printf("ls:简略输出该目录下所有目录项\n");
	printf("ls -l:详细输出该目录下所有目录项(时间，所属用户，权限等等)\n");
	printf("md [文件夹名称]：创建文件夹\n");
	printf("create [文件名称][.文件后缀]：创建文件\n");
	printf("rm [文件夹名称]：删除文件夹\n");
	printf("delete [文件名称][.文件后缀]：删除文件\n");
	printf("catFAT [文件名称][.文件后缀]：显示文件分配表\n");
	printf("catStorge：显示外存存储状态\n");
	printf("catUsers：显示所有用户\n");
	printf("new user:root用户下创建新用户\n");
	printf("logout:退出登录\n");
	printf("open [文件名称][.文件后缀]:将文件夹打开（打开后，只能执行 write read 和close）\n");
	printf("close [文件名称][.文件后缀]：将文件从打开列表中移除\n");
	printf("read [文件名称][.文件后缀]:读取某文件内容\n");
	printf("write [文件名称][.文件后缀]:项某文件写内容 结尾输入回车:wq回车结束写入操作\n");
	printf("su [用户名]：用于切换用户\n");
	printf("help：输出命令文档，此文档。\n");
	printf("catOpen：查看打开文件表\n");
	printf("whoami:查看当前用户的用户名\n");
	printf("cd [文件夹名称]:进入某一目录\n");
	printf("cl:清屏\n");
	printf("pwd:输出当前路径\n");
	printf("open [文件名称][.文件后缀]：打开某一文件到内存");
	printf("close [文件名称][.文件后缀]：将某一文件总文件打开表移除");
	printf("catOpen:查看已经打开的文件列表");
	printf("\n*************************************\n");
	return;
}
int main(int argc, char *argv[]) {
	//writeFileContent();
	userListInit();
	root = InitFileSystem();
	FCB_Ptr currentFCB_Ptr = root;
	char operation[OPMAXN];
	testDirectory(root);
	storgeInit();
//	initOpen();
	initOpen();
	while (1) {
		printf("Login:");
		char username[16];
		scanf("%s",username);
		getchar();
		printf("%s@192.168.131.88's password:",username);
		char pass[16];
		password_code(pass);
		printf("\n");
		if(checkUser(username, pass) == 1){
			//认证成功
			//displayUserList();
			//	display_StorgeStatus();
			while (1) {
				printf("%s@192.168.131.88:%s#",currentUser->username,currentFCB_Ptr->path);
				gets(operation);
				char *op = strtok(operation, " ");
				char *arg = strtok(NULL, " "); //以上分割出操作命令和参数，比如cd music，则命令为cd，参数为musi
				if(arg != NULL &&strcmp(arg, "..") != 0 && strcmp(arg, ".") != 0 && strcmp(arg, "./") 
					!= 0 && strcmp(arg, "../") != 0)
					arg = strtok(arg, ".");
				char *end = strtok(NULL,".");
				if(op == NULL)
					{
						printf("无效命令\n");
					}
				else if(strcmp(op, "md") == 0)
					{
						if(arg == NULL)
							printf("无效命令\n");
						else
							makeDirectory(currentFCB_Ptr, arg);
					}
				else if(strcmp(op, "create") == 0)
					{
						
						if(arg == NULL)
							printf("无效命令\n");
						else{
							if(end != NULL)
								{
									makeFile(currentFCB_Ptr, arg, end);
								}
							else{
								printf("无效后缀名\n");
							}
						}
					}
				else if(strcmp(op, "delete") == 0)
					{
						
						if(arg == NULL)
							printf("无效命令\n");
						else{
							if(end != NULL)
								{
									deleteFile(findByName(arg, currentFCB_Ptr, end));
								}
							else{
								printf("无效后缀名\n");
							}
						}
					}

				else if(strcmp(op, "cd") ==0 )
					{
						//					char *temp = strtok(operation, ".");
						////					char *p =  strtok(NULL, " ");
						//					printf("--%s\n",arg);
						
						if(arg == NULL)
							printf("无效命令\n");
						else if(strcmp(arg, "..") == 0 || strcmp(arg, "../") == 0)
							{
								if(currentFCB_Ptr->parent!=NULL)
									currentFCB_Ptr = currentFCB_Ptr->parent;
							}
						
						else{
							FCB_Ptr temp =  EnterTheDirectory(currentFCB_Ptr, arg);
							if(temp!=NULL){
								currentFCB_Ptr = temp;
							}else{
								printf("无效文件目录\n");
							}
						}
					}
				else if(strcmp(op, "ls") ==0 )
					{
						if(arg != NULL && strcmp(arg, "-l") == 0){
							//输出详细信息
							showCurrentDirectoryAllFileDetail(currentFCB_Ptr);
						}
						else 
							showCurrentDirectoryAllFile(currentFCB_Ptr);
					}
				else if(strcmp(op, "rm") ==0 )//删除文件夹及以下所有内容
					{
						if(arg == NULL)
							printf("无效命令\n");
						else
							DeleteFCB(currentFCB_Ptr,arg);
					}
				else if(strcmp(op, "write") ==0 )
					{
						if(arg == NULL)
							printf("无效命令\n");
						else{
							if(end != NULL)
								{
									FCB_Ptr p = findByName(arg, currentFCB_Ptr, end);
									writeFileContent(p);
								}
							else{
								printf("无效后缀名\n");
							}
						}					
					}
				else if(strcmp(op, "read") ==0 )
					{
						if(arg == NULL)
							printf("无效命令\n");
						else{
							if(end != NULL)
								{
									FCB_Ptr file = findByName(arg, currentFCB_Ptr, end);
									readFileContent(file);
								}
							else{
								printf("无效后缀名\n");
							}
						}					
					}
				else if(strcmp(op, "whoami") == 0)//查询是哪个用户
					{
						printf("%s\n",currentUser->username);
					}
				else if(strcmp(op, "su") == 0)//切换用户
					{
						//printf("%s",arg); username = arg
						printf("password:");
						password_code(pass);
						checkUser(username, pass);
					}
				else if(strcmp(op, "new") == 0)//切换用户
				{
					//printf("%s",arg); username = arg
					if(strcmp(currentUser->username, "root") == 0)
					{
						printf("请输入用户名：");
						scanf("%s",username);
						printf("请输入密码：");
						getchar();
						password_code(pass);
						newUser(username, pass);
						printf("\n创建成功！！\n");
						makeDirectory(root->files[2], username);
					}
					else{
						
						printf("该用户下没有权限创建新用户!\n");
					}
				}
				else if(strcmp(op, "catFAT") == 0)
					{
						
						FCB_Ptr file = findByName(arg, currentFCB_Ptr, end);
						displayFileFAT(file);
					}
				
				else if(strcmp(op, "catStorge") == 0)
					{
						
						display_StorgeStatus();
					}
				else if(strcmp(op, "catOpen") == 0)
					{
						
//						dispalyOpenTable();
					}
				else if(strcmp(op, "open") == 0)
					{
						FCB_Ptr file = findByName(arg, currentFCB_Ptr, end);
//						if(file != NULL)
//							openFile(file);	
					}
			else if(strcmp(op, "close") == 0)
							{
								
								FCB_Ptr file = findByName(arg, currentFCB_Ptr, end);
//								if(file != NULL)
//									closeFile(file);
					}
				else if(strcmp(op, "cl") == 0)
					{
						printf("\x1b[H\x1b[2J");
					}
				else if(strcmp(op, "help") == 0)
					{
						help();
					}
				else if(strcmp(op, "logout") == 0)
					{
						break;
					}
				else if(strcmp(op, "pwd") ==0 ){
					printf("%s\n",currentFCB_Ptr->path);
				}
//				break;
			}
		}else{
			printf("\n账号或密码错误。请重试！\n");
		}

	}
}